package com.easylinkin.linkappapi.elasticsearch.service;

import com.baomidou.mybatisplus.extension.service.additional.query.impl.LambdaQueryChainWrapper;
import com.easylinkin.bases.redis.util.RedisUtil;
import com.easylinkin.linkappapi.calculaterule.entity.CalculateConfig;
import com.easylinkin.linkappapi.calculaterule.service.CalculateConfigService;
import com.easylinkin.linkappapi.common.utils.DateUtil;
import com.easylinkin.linkappapi.common.utils.message.SendEmailUtil;
import com.easylinkin.linkappapi.tenant.entity.LinkappTenant;
import com.easylinkin.linkappapi.tenant.mapper.LinkappTenantMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * etl 统计监测器
 * 当出现etl统计错误时会进行一些辅助功能，比如发邮件通知
 * 比如监测到etl 定时任务停止n天没有运行，也会进行监测发邮件告警
 * @author tongjie
 */
@Service
@Slf4j
public class EtlStatisticMonitorService {
    final String[] receiveEmailAddress = {"tongjie@easylinkin.com"};
    @Resource
    private CalculateConfigService calculateConfigService;
    @Resource
    private LinkappTenantMapper linkappTenantMapper;
    @Resource
    private SendEmailUtil sendEmailUtil;
    @Resource
    private RedisUtil redisUtil;


    /**
     * 检查etl 能耗统计有负数问题,若出现则发邮件通知
     *
     * @param esPostBody2 统计后要插入es的统计数据
     */
    public void checkErrorEtlStatistic(Map<String, Object> esPostBody2) {
//        续命24小时，当key开始失效，说明有1天以上没有统计了
        redisUtil.set("checkEtlStatisticStillRun", "etl-statistic-occur-" + DateUtil.getYYYYMMDDHHMMSSDate(new Date()), 60 * 60 * 24);
        String calcTime = "" + esPostBody2.get("calcTime");
        List<Map<String, Object>> items = (List<Map<String, Object>>) esPostBody2.get("items");
        if (items == null) {
            return;
        }
        List<Map<String, Object>> errorList = new ArrayList<>();
        for (Map<String, Object> item : items) {
            Object actualDay = item.get("actualDay");
            if (actualDay != null) {
                String deviceCode = (String) item.get("deviceCode");
                Map<String, Object> map = new LinkedHashMap<>(100);
                map.put("计算值", actualDay);
                map.put("设备编号", deviceCode);
                errorList.add(map);
            }
        }
        if (errorList.size() == 0) {
            return;
        }
        LinkedHashMap<String, String> notifyMap = new LinkedHashMap<>(20);
        String calcCfgId = esPostBody2.get("calcCfgId").toString();
        CalculateConfig calculateConfig = calculateConfigService.getById(calcCfgId);
        if (calculateConfig != null) {
            LinkappTenant tenant = new LambdaQueryChainWrapper<>(linkappTenantMapper)
                    .select(LinkappTenant::getPlatformProjectName, LinkappTenant::getId)
                    .eq(LinkappTenant::getId, calculateConfig.getTenantId())
                    .one();
            String projectName = tenant.getPlatformProjectName();
            notifyMap.put("项目名称", projectName);
            notifyMap.put("计算配置名称", calculateConfig.getName());
            notifyMap.put("计算配置id", calculateConfig.getId());
        }
        notifyMap.put("异常详情", errorList.toString());
        notifyMap.put("统计时间", calcTime);
        notifyMap.put("数据源id", "" + esPostBody2.get("dataSourceId"));
        notifyMap.put("jobId", "" + esPostBody2.get("jobId"));

        log.info("etl统计监测到异常数据输入:{}", notifyMap);
        StringBuilder stringBuilder = new StringBuilder();
        notifyMap.forEach((key,val)->{
            stringBuilder.append(key).append(":").append(val).append("<br>");
        });
        log.info("能耗统计参数负数数据了:{}", stringBuilder);
        //        解决每个小时都发邮件太烦人，只监测 几个小时点期间的
        if (calcTime.endsWith("00") || calcTime.endsWith("09") || calcTime.endsWith("10")) {
            sendEmailUtil.send(receiveEmailAddress, stringBuilder.toString(), "能耗统计监测异常");
        }
    }

    public static void main(String[] args) {
        String[] s1 = Collections.singletonList("AAA123").toArray(new String[1]);
        System.out.println(s1[0]);
    }

    /**
     * 检测etl统计任务长时间停止
     */
    public void sendEtlErrorEmail() {
        sendEmailUtil.send(receiveEmailAddress, "AEP 能耗统计任务监测到停止了,kettle定时任务可能异常停止了，请去aep检查", "能耗统计任务监测到停止了");
    }

}
